/*
* Copyright (c) 2008, Vladimir Gumenuk
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*     * Redistributions of source code must retain the above copyright
*       notice, this list of conditions and the following disclaimer.
*     * Redistributions in binary form must reproduce the above copyright
*       notice, this list of conditions and the following disclaimer in the
*       documentation and/or other materials provided with the distribution.
*     * Neither the name of the copyright holder nor the
*       names of its contributors may be used to endorse or promote products
*       derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

// RealGNX4LibDoc.cpp : implementation of the CRealGNX4LibDoc class
//

#include "stdafx.h"
#include "RealGNX4Lib.h"
#include "GP4File.h"
#include "RealGNX4LibDoc.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif


// CRealGNX4LibDoc

IMPLEMENT_DYNCREATE(CRealGNX4LibDoc, CDocument)

BEGIN_MESSAGE_MAP(CRealGNX4LibDoc, CDocument)
END_MESSAGE_MAP()


// CRealGNX4LibDoc construction/destruction

CRealGNX4LibDoc::CRealGNX4LibDoc()
{
	// TODO: add one-time construction code here
}

CRealGNX4LibDoc::~CRealGNX4LibDoc()
{
}

BOOL CRealGNX4LibDoc::OnNewDocument()
{
	if (!CDocument::OnNewDocument())
		return FALSE;

	// TODO: add reinitialization code here
	// (SDI documents will reuse this document)
/*
    PRESET pst;
    ZeroMemory( &pst, sizeof(PRESET) );
    LoadGP4File( "E:\\WORK\\Investigation\\RealGNX4Lib\\doc\\YAYA.g4p", &pst );

    //CGNX4TblFile localTBL;
    //localTBL.Load( "E:\\Work\\gnx4librarian\\doc\\presets_latest.tbl" );

    LPPRESET lpTest = m_TBL.GetPreset( 79 ); // original
    LPPRESET lpTest2 = &pst; //m_TBL.GetPreset( 1 );
    //LPPRESET lpTest3 = localTBL.GetPreset( 79 );

    if( !ComparePresets( lpTest, lpTest2 ) )
    {
        TRACE( "!= ComparePresets =! \n" );
    }
*/
/*  if( !CompareAmpModels( &lpTest->Amp1, &lpTest2->Amp1 ))
    {
        TRACE( "Dumping Original YAYA Amp1\n" );
        DumpGNXAmp( &lpTest->Amp1 );

        TRACE( "Dumping Loaded YAYA Amp1\n" );
        DumpGNXAmp( &lpTest2->Amp1 );
    }

    if( !CompareAmpModels( &lpTest->Amp2, &lpTest2->Amp2 ))
    {
        TRACE( "Dumping Original YAYA Amp2\n" );
        DumpGNXAmp( &lpTest->Amp2 );

        TRACE( "Dumping Loaded YAYA Amp2\n" );
        DumpGNXAmp( &lpTest2->Amp2 );
    }
*/
/*
    if( !CompareAmpModels( &lpTest->Amp1, &lpTest3->Amp1 ))
    {
        TRACE( "Dumping Original YAYA Amp1\n" );
        DumpGNXAmp( &lpTest->Amp1 );

        TRACE( "Dumping Loaded YAYA Amp1\n" );
        DumpGNXAmp( &lpTest2->Amp1 );
    }

    if( !CompareAmpModels( &lpTest->Amp2, &lpTest3->Amp2 ))
    {
        TRACE( "Dumping Original YAYA Amp2\n" );
        DumpGNXAmp( &lpTest->Amp2 );

        TRACE( "Dumping Loaded YAYA Amp2\n" );
        DumpGNXAmp( &lpTest2->Amp2 );
    }
*/
    //CGP4File file;
    //CGP4File::LoadAllParams( "D:\\DOC\\Music\\DigiTech\\StdPresets", file, m_TBL.GetPresets() );
    //file.TraceParams();
/*
    for( DWORD i = 0; i < GNX_MAX_PRESETS; i++ )
    {
        LPPRESET lpPr = m_TBL.GetPreset( i ); 
        TRACE( "\n----------------------------------------------------\n[%d] Dumping Unknown data block:\n", i+1 );
        PrintHexDump( (LPBYTE)&lpPr->wUnkData[0], 120 );
    }
*/
/*    TRACE( "Comparing unknown data:\n" );

    for( DWORD i = 0; i < GNX_MAX_PRESETS; i++ )
    {
        LPPRESET lpPrTest = m_TBL.GetPreset( i ); 

        for( DWORD x = 0; x < GNX_MAX_PRESETS; x++ )
        {
            LPPRESET lpPr = m_TBL.GetPreset( x ); 
            if( i == x )
                continue;

            if( memcmp( lpPrTest->wUnkData, lpPr->wUnkData, 120 ) == 0 )
            {
                TRACE( "Unknown data equal: [%d] == [%d]\n", i+1, x+1 );
            }

            if( memcmp( lpPrTest->bAmp1Data, lpPr->bAmp1Data, sizeof(lpPr->bAmp1Data) ) == 0 )
            {
                TRACE( "Amp1 data equal: [%d] == [%d]\n", i+1, x+1 );
            }

            if( memcmp( lpPrTest->bAmp2Data, lpPr->bAmp2Data, sizeof(lpPr->bAmp2Data) ) == 0 )
            {
                TRACE( "Amp2 data equal: [%d] == [%d]\n", i+1, x+1 );
            }

            if( memcmp( lpPrTest->bCab1Data, lpPr->bCab1Data, sizeof(lpPr->bCab1Data) ) == 0 )
            {
                TRACE( "Cab1 data equal: [%d] == [%d]\n", i+1, x+1 );
            }

            if( memcmp( lpPrTest->bCab2Data, lpPr->bCab2Data, sizeof(lpPr->bCab2Data) ) == 0 )
            {
                TRACE( "Cab2 data equal: [%d] == [%d]\n", i+1, x+1 );
            }
        }
    }
/*
    TRACE( "\nDumping all unknown params:\n" );
    TRACE( "\tUnk1\tUnk2\tUnk3\tUnk4\tUnk5\tUnk6\tUnk7\tUnk8\tUnk9\tUnk10" 
           "\tUnk11\tUnk12\tUnk13\tUnk14\tUnk15\tUnk16\tUnk17\tUnk18\tUnk19\tUnk20"
           "\tUnk21\tUnk22\tUnk23\tUnk24\tUnk25\tUnk26\tUnk27\tUnk28\tUnk29\tUnk30"
           "\tUnk31\tUnk32\tUnk33\tUnk34\tUnk35\n"
        );

    for( DWORD i = 0; i < GNX_MAX_PRESETS; i++ )
    {
        LPPRESET p = m_TBL.GetPreset( i ); 
        TRACE( "\t0x%04X\t0x%04X\t0x%04X\t0x%04X\t0x%04X\t0x%04X\t0x%04X\t0x%04X\t0x%04X\t0x%04X"
            "\t0x%04X\t0x%04X\t0x%04X\t0x%04X\t0x%04X\t0x%04X\t0x%04X\t0x%04X\t0x%04X\t0x%04X"
            "\t0x%04X\t0x%04X\t0x%04X\t0x%04X\t0x%04X\t0x%04X\t0x%04X\t0x%04X\t0x%04X\t0x%04X"
            "\t0x%04X\t0x%04X\t0x%04X\t0x%04X\t0x%04X\n",
            p->wUnknown1, p->wUnknown2, p->wUnknown3, p->wUnknown4, p->wUnknown5, p->wUnknown6, p->wUnknown7, p->wUnknown8, p->wUnknown9, p->wUnknown10,
            p->wUnknown11, p->wUnknown12, p->wUnknown13, p->wUnknown14, p->wUnknown15, p->wUnknown16, p->wUnknown17, p->wUnknown18, p->wUnknown19, p->wUnknown20,
            p->wUnknown21, p->wUnknown22, p->wUnknown23, p->wUnknown24, p->wUnknown25, p->wUnknown26, p->wUnknown27, p->wUnknown28, p->wUnknown29, p->wUnknown30,
            p->wUnknown31, p->wUnknown32, p->wUnknown33, p->wUnknown34, p->wUnknown35
            );    
    }

    TRACE( "\nDumping unknown 60 words blocks:\n" );

    for( DWORD i = 0; i < 60; i++ )
    {
        TRACE( "%05d\t", i+1 );
    }
    TRACE( "\n" );

    for( DWORD i = 0; i < GNX_MAX_PRESETS; i++ )
    {
        LPPRESET p = m_TBL.GetPreset( i ); 

        for( DWORD x = 0; x < 60; x++ )
        {
            TRACE( "0x%04X\t", p->wUnkData[x] );
        }
        TRACE( "\n" );
    }

    for( DWORD i = 0; i < GNX_MAX_PRESETS; i++ )
    {
        LPPRESET p = m_TBL.GetPreset( i ); 

        LPBYTE pb = &p->bAmp2Data[0] + 788-36;
        for( DWORD x = 0; x < 36; x++ )
        {
            TRACE( "%02X ", *pb++ );
        }
        TRACE( "\n" );
    }
*/
	return TRUE;
}

void TraceGNXAssign( LPPRESET p )
{
    TRACE( "--------------------------------\n" );
    TRACE( "dwEXPPdl1Assign     0x%08X\n", p->wEXPPdl1Assign    );
    TRACE( "dwEXPPdl2Assign     0x%08X\n", p->wEXPPdl2Assign    );
    TRACE( "dwEXPPdl3Assign     0x%08X\n", p->wEXPPdl3Assign    );
    TRACE( "dwLFO1Assign        0x%08X\n", p->wLFO1Assign       );
    TRACE( "dwLFO2Assign        0x%08X\n", p->wLFO2Assign       );
    TRACE( "dwCTRLA_Lnk1_Assign 0x%08X\n", p->wCTRLA_Lnk1_Assign);
    TRACE( "dwCTRLA_Lnk2_Assign 0x%08X\n", p->wCTRLA_Lnk2_Assign);
    TRACE( "dwCTRLA_Lnk3_Assign 0x%08X\n", p->wCTRLA_Lnk3_Assign);
    TRACE( "dwCTRLB_Lnk1_Assign 0x%08X\n", p->wCTRLB_Lnk1_Assign);
    TRACE( "dwCTRLB_Lnk2_Assign 0x%08X\n", p->wCTRLB_Lnk2_Assign);
    TRACE( "dwCTRLB_Lnk3_Assign 0x%08X\n", p->wCTRLB_Lnk3_Assign);
    TRACE( "dwCTRLC_Lnk1_Assign 0x%08X\n", p->wCTRLC_Lnk1_Assign);
    TRACE( "dwCTRLC_Lnk2_Assign 0x%08X\n", p->wCTRLC_Lnk2_Assign);
    TRACE( "dwCTRLC_Lnk3_Assign 0x%08X\n", p->wCTRLC_Lnk3_Assign);
    TRACE( "--------------------------------\n" );
}

// CRealGNX4LibDoc serialization
BOOL CRealGNX4LibDoc::OnOpenDocument( LPCTSTR lpszPathName )
{
    BOOL bRet = m_TBL.Load( lpszPathName );

    if( bRet )
    {
        TraceGNXAssign( GetPreset( 0 ) );
    }

    return bRet;
}

BOOL CRealGNX4LibDoc::OnSaveDocument( LPCTSTR lpszPathName )
{
    BOOL bRet = m_TBL.Save( lpszPathName );

    if( bRet )
    {
        SetModifiedFlag( FALSE );
    }

    return bRet;
}

// CRealGNX4LibDoc diagnostics

#ifdef _DEBUG
void CRealGNX4LibDoc::AssertValid() const
{
    CDocument::AssertValid();
}

void CRealGNX4LibDoc::Dump(CDumpContext& dc) const
{
    CDocument::Dump(dc);
}
#endif //_DEBUG


// CRealGNX4LibDoc commands
LPPRESET CRealGNX4LibDoc::GetPreset( UINT iIdx )
{
    if( iIdx >= GNX_MAX_PRESETS )
        return 0;

    LPPRESET p = m_TBL.GetPresets();
    return &p[iIdx];
}

BOOL CRealGNX4LibDoc::MovePresetUp( UINT iIdx )
{
    BOOL bRet = m_TBL.MovePresetUp( iIdx );
    
    if( bRet )
        SetModifiedFlag();

    return bRet;
}

BOOL CRealGNX4LibDoc::MovePresetDown( UINT iIdx )
{
    BOOL bRet = m_TBL.MovePresetDown( iIdx );

    if( bRet )
        SetModifiedFlag();

    return bRet;
}

BOOL CRealGNX4LibDoc::LoadGP4File( LPCSTR lpszPathName, LPPRESET pOut )
{
    if( !lpszPathName || !pOut )
        return FALSE;

    CGP4File gpFile;
    return gpFile.Load( lpszPathName, pOut );
}

BOOL CRealGNX4LibDoc::LoadGP4FileToPreset( LPCSTR lpszFileName, UINT iPlaceIdx )
{
    if( !lpszFileName || iPlaceIdx >= GNX_MAX_PRESETS )
        return FALSE;

    LPPRESET pPreset = m_TBL.GetPreset( iPlaceIdx );

    PRESET pr;
    memcpy( &pr, pPreset, sizeof(PRESET) );

    BOOL bRet = LoadGP4File( lpszFileName, pPreset );
    if( bRet )
        SetModifiedFlag();
    else
        memcpy( pPreset, &pr, sizeof(PRESET) );

    return bRet;
}

void CRealGNX4LibDoc::TestLoadedPresetAmpCab( LPPRESET p )
{
/*    for( DWORD i = 0; i < GNX_MAX_PRESETS; i++ )
    {
        LPPRESET pPr = m_TBL.GetPreset( i );
        if( wcscmp( p->Amp1.wszName, pPr->Amp1.wszName ) == 0 )
        {
            if( memcmp( p->bAmp1Data, pPr->bAmp1Data, sizeof(pPr->bAmp1Data) ) != 0 )
            {
                TRACE( "Amp1 data doesnt match!\n" );

                TRACE( "Amp1 loaded data:\n" );
                PrintHexDump( p->bAmp1Data, sizeof(pPr->bAmp1Data) );

                TRACE( "\nAmp1 orogonal data:\n" );
                PrintHexDump( pPr->bAmp1Data, sizeof(pPr->bAmp1Data) );
                break;
            }
        }

        if( wcscmp( p->wszAmp2Name, pPr->wszAmp2Name ) == 0 )
        {
            if( memcmp( p->bAmp2Data, pPr->bAmp2Data, sizeof(pPr->bAmp2Data) ) != 0 )
            {
                TRACE( "Amp2 data doesnt match!\n" );

                TRACE( "Amp2 loaded data:\n" );
                PrintHexDump( p->bAmp2Data, sizeof(pPr->bAmp2Data) );

                TRACE( "\nAmp2 orogonal data:\n" );
                PrintHexDump( pPr->bAmp2Data, sizeof(pPr->bAmp2Data) );
                break;
            }
        }

        if( wcscmp( p->wszCab1Name, pPr->wszCab1Name ) == 0 )
        {
            if( memcmp( p->bCab1Data, pPr->bCab1Data, sizeof(pPr->bCab1Data) ) != 0 )
            {
                TRACE( "Cab1 data doesnt match!\n" );
            }
        }

        if( wcscmp( p->wszCab2Name, pPr->wszCab2Name ) == 0 )
        {
            if( memcmp( p->bCab2Data, pPr->bCab2Data, sizeof(pPr->bCab2Data) ) != 0 )
            {
                TRACE( "Cab2 data doesnt match!\n" );
            }
        }
    }*/
}